﻿using System;
using System.Collections;
using System.Collections.Specialized;
using System.Data;
using System.Reflection;
using System.Text;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Xml;
using AMS.Core.Entities;
using AMS.Core.Manager;
using AMS.WorkBill.DataAccess;
using AMS.WorkBill.Entities;
using VitCode.BaseDataPageCreator;
using VitCode.BaseDataPageCreator.Setting;
using VitCode.Castle.DataAccess;
using VitCode.Web.UI.WebControls;

namespace AMS.Web.WorkBill
{
    public class WoPageBuilder
    {
        private WoRuleHelper m_RuleHelper;
        private const string EXEC_ERR_MSG = "ExecErrMsg";

        public static string EDIT = "Edit",
                             EXEC = "Exec";

        public static string GET_FROM_OBJ_PRO = "GetFromObjPro";
        public static string IMPORTOR = "";
        public static string INIT = "Init";

        public static string PRO_VALUE_INFO = "ProValueInfo",
                             SESSION_OBJECT_HEAD_STRING = "WoPageBuilder_";

        public static string VALUE_FROM_WO_OBJ_PRO = "ValueFromWoObjPro";
        private Page m_Page;

        private PageBuilder m_PageBuilder;
        private PageSaveHelper m_PageSaveHelper;

        public WoPageBuilder(Page page, string settingXmlPath)
        {
            m_Page = page;
            m_PageSaveHelper = new PageSaveHelper(page, settingXmlPath);
            m_PageBuilder = new PageBuilder(page, settingXmlPath);
            m_RuleHelper = new WoRuleHelper();
        }

        public PageBuilder CurrPageBuilder
        {
            get { return m_PageBuilder; }
        }

        public PageSaveHelper CurrPageSaveHelper
        {
            get { return m_PageSaveHelper; }
        }

        public PageLoadHelper CurrPageLoadHelper
        {
            get { return m_PageBuilder.m_LoadHelper; }
        }

        public ObjXmlReader CurrObjXmlReader
        {
            get { return m_PageBuilder.m_LoadHelper.XmlReader; }
        }

        public bool WoIsClose()
        {
            WorkBillInfo obj = GetCurrSessionWoInfo(m_Page);
            if (obj != null && obj.State == WorkBillInfo.STATE_CLOSE)
                return true;
            return false;
        }


        public object GetSessionObject(string strKey)
        {
            return m_Page.Session[SESSION_OBJECT_HEAD_STRING + strKey];
        }


        public void SetSessionObject(string strKey, object val)
        {
            m_Page.Session[SESSION_OBJECT_HEAD_STRING + strKey] = val;
        }


        public WorkBillInfo GetCurrSessionWoInfo(Page currPage, string woInfoId)
        {
            object reVal = currPage.Session[WorkBillInfo.PAGE_SESSION_NAME];
            if (reVal == null)
            {
                SetCurrSessionWoInfo(currPage, woInfoId);
                reVal = currPage.Session[WorkBillInfo.PAGE_SESSION_NAME];
            }
            if (reVal != null && reVal is WorkBillInfo)
                return (WorkBillInfo) reVal;
            return null;
        }

        public WorkBillInfo GetCurrSessionWoInfo(Page currPage)
        {
            return GetCurrSessionWoInfo(currPage, "");
        }

        public void SetCurrSessionWoInfo(Page currPage, string woInfoId)
        {
            if (woInfoId.Length == 36)
            {
                var acc = new WorkBillAccess();
                try
                {
                    object objVal = acc.GetSingleObjectById(typeof (WorkBillInfo).Name, woInfoId);
                    if (objVal != null && objVal is WorkBillInfo)
                        currPage.Session[WorkBillInfo.PAGE_SESSION_NAME] = objVal;
                }
                finally
                {
                    acc.CloseSession();
                }
            }
        }

        public void SetCurrSessionWoInfoByCode(Page currPage, string woCode)
        {
            if (woCode.Length == 14)
            {
                var acc = new WorkBillAccess();
                try
                {
                    object objVal = acc.GetSingleObjectByProVal(typeof (WorkBillInfo).Name, "Code", woCode);
                    if (objVal != null && objVal is WorkBillInfo)
                        currPage.Session[WorkBillInfo.PAGE_SESSION_NAME] = objVal;
                }
                finally
                {
                    acc.CloseSession();
                }
            }
        }

        public void SetCurrSessionWoInfo(Page currPage, WorkBillInfo woInfo)
        {
            currPage.Session[WorkBillInfo.PAGE_SESSION_NAME] = woInfo;
        }

        public void ClearCurrWoInfo(Page currPage)
        {
            currPage.Session[WorkBillInfo.PAGE_SESSION_NAME] = null;
        }

        public string CreateProHqlCondition(string strProValInfo)
        {
            var sb = new StringBuilder();

            if (strProValInfo != null && strProValInfo.Length > 0)
            {
                string[] ss = strProValInfo.Split(',');
                foreach (string str in ss)
                {
                    string[] keyVal = str.Split(':');
                    if (keyVal.Length == 2)
                    {
                        if (sb.Length > 0)
                            sb.Append(" and ");
                        sb.Append("(o." + keyVal[0] + "='" + keyVal[1] + "')");
                    }
                }
            }
            return sb.ToString();
        }

        private object GetFromObjProVal(XmlNode proNode, object obj)
        {
            if (obj == null)
                return null;
            string strGetFromObjPro = m_PageSaveHelper.GetNodeAttributeValue(proNode, GET_FROM_OBJ_PRO, true);
            if (strGetFromObjPro.Length > 0)
            {
                string[] ss = strGetFromObjPro.Split('.');
                if (ss.Length == 2)
                {
                    PropertyInfo pi = obj.GetType().GetProperty(ss[0]);
                    if (pi != null)
                    {
                        object objPro = pi.GetValue(obj, null);
                        if (objPro != null)
                        {
                            PropertyInfo pi2 = objPro.GetType().GetProperty(ss[1]);
                            if (pi2 != null)
                            {
                                object objProVal2 = pi2.GetValue(objPro, null);
                                return objProVal2;
                            }
                        }
                    }
                }
            }
            return null;
        }

        private object GetValueFromWoObjPro(XmlNode proNode, object obj)
        {
            if (obj == null)
                return null;
            string strValueFromWoObjPro = m_PageSaveHelper.GetNodeAttributeValue(proNode, VALUE_FROM_WO_OBJ_PRO, true);
            if (strValueFromWoObjPro.Length > 0)
            {
                object woInfo = GetCurrSessionWoInfo(m_Page);
                if (woInfo == null)
                    throw new ArgumentException("Session中的WoInfo对象不能为空");
                PropertyInfo pi = woInfo.GetType().GetProperty(strValueFromWoObjPro);
                if (pi != null)
                {
                    object objProVal = pi.GetValue(woInfo, null);
                    return objProVal;
                }
            }
            return null;
        }

        private object GetValFormProValueInfo(XmlNode proNode, BaseDataAccess acc)
        {
            string strName = m_PageSaveHelper.GetNodeAttributeValue(proNode, m_PageBuilder.m_LoadHelper.NAME, false);
            string strProValueInfo = m_PageSaveHelper.GetNodeAttributeValue(proNode, PRO_VALUE_INFO, true);
            string strClassName = m_PageSaveHelper.GetNodeAttributeValue(proNode, m_PageBuilder.m_LoadHelper.CLASS_NAME,
                                                                         true);
            if (strProValueInfo.Length > 0 && strClassName.Length > 0)
            {
                string strSessionKey = strName + "_" + strProValueInfo;
                object objVal = GetSessionObject(strSessionKey);
                if (objVal == null)
                {
                    string strHqlCondition = CreateProHqlCondition(strProValueInfo);
                    if (strHqlCondition.Length == 0)
                        return null;
                    string strHql = "From " + strClassName + " o where " + strHqlCondition;
                    IList lstObjs = acc.Session.CreateQuery(strHql).List();
                    if (lstObjs != null && lstObjs.Count > 0)
                        SetSessionObject(strSessionKey, lstObjs[0]);
                }

                objVal = GetSessionObject(strSessionKey);
                return objVal;
            }
            return null;
        }

        public void SetInitCommandPro(WoCommand comm, XmlNode proNode, BaseDataAccess acc)
        {
            if (comm == null || proNode == null || acc == null)
                return;
            string strName = m_PageSaveHelper.GetNodeAttributeValue(proNode, m_PageBuilder.m_LoadHelper.NAME, false);
            try
            {
                if (proNode.Attributes.Count == 0)
                    return;

                PropertyInfo commPi = comm.GetType().GetProperty(strName);
                if (commPi == null)
                    return;

                object val = GetFromObjProVal(proNode, comm) ?? GetValFormProValueInfo(proNode, acc);
                if (val != null)
                    commPi.SetValue(comm, val, null);
            }
            catch (Exception ex)
            {
                m_PageBuilder.m_LoadHelper.XmlReader.ShowErrorSettingInfo(proNode, ex);
            }
        }

        public void SetInitCommandProSet(WoCommand comm, string woClassName, string woTypeName)
        {
            XmlNodeList nl =
                m_PageBuilder.m_LoadHelper.XmlReader.GetNodeList("Setting/" + woClassName + "/" + woTypeName +
                                                                 "/commandSetting/CommandPros/" + INIT + "/property");
            var acc = new BaseDataAccess();
            foreach (XmlNode n in nl)
            {
                m_PageSaveHelper.SetObjectPropetyValue(comm, n, acc);
            }
        }


        public void SetTableData(HtmlTable tblContextInfo, XmlNodeList nl, UserControl uc)
        {
            object objWoInfo = GetCurrSessionWoInfo(m_Page);
            foreach (XmlNode proNode in nl)
            {
                string strName = CurrPageBuilder.GetNodeAttributeValue(proNode, CurrPageLoadHelper.NAME, false);


                Control c = uc.FindControl(CurrPageLoadHelper.OBJ_PRO_HEAD_STRING + strName);
                if (c != null)
                {
                    string strKeyPro = CurrPageBuilder.GetNodeAttributeValue(proNode, CurrPageLoadHelper.CTL_OBJ_KEY_PAO,
                                                                             true);
                    PropertyInfo ctlPi = null;
                    if (strKeyPro.Length > 0)
                        ctlPi = c.GetType().GetProperty(strKeyPro);
                    if (ctlPi == null)
                        ctlPi = c.GetType().GetProperty("Text");
                    if (ctlPi != null)
                    {
                        object val = GetFromObjProVal(proNode, objWoInfo) ??
                                     GetValFormProValueInfo(proNode, new BaseDataAccess())
                                     ?? GetValueFromWoObjPro(proNode, objWoInfo);
                        if (val != null)
                            ctlPi.SetValue(c, val, null);
                    }
                }
            }
        }

        public string GetPageKeyField(string className)
        {
            return CurrPageBuilder.m_LoadHelper.SetObjectKeyField(className);
        }

        private XmlNodeList GetCommandEditProList(string woClassName, string woTypeName)
        {
            return m_PageBuilder.m_LoadHelper.XmlReader.GetNodeList("Setting/" + woClassName + "/" + woTypeName +
                                                                    "/commandSetting/CommandPros/" + EDIT + "/property");
        }

        public XmlNodeList GetCommandImportorProList(string woClassName, string woTypeName)
        {
            return m_PageBuilder.m_LoadHelper.XmlReader.GetNodeList("Setting/" + woClassName + "/" + woTypeName +
                                                                    "/commandSetting/CommandPros/" + IMPORTOR +
                                                                    "/Column");
        }

        public void SetTableData(HtmlTable tblContextInfo, string woClassName, string woTypeName, UserControl uc)
        {
            XmlNodeList nl = GetCommandEditProList(woClassName, woTypeName);
            SetTableData(tblContextInfo, nl, uc);
        }


        public void SetCommandSetTableInfo(HtmlTable tblContextInfo, string woClassName, string woTypeName)
        {
            XmlNodeList nl = GetCommandEditProList(woClassName, woTypeName);
            CurrPageBuilder.SetTableInfoContext(tblContextInfo, nl, typeof (WoCommand));
        }

        public void ShowAssetInfoByAssetInfoId(string strId, Page currPage)
        {
            PageLoadHelper loadHelper = CurrPageLoadHelper;
            var manager = new CoreManager();
            AssetInfo ai = manager.GetAssetInfo(strId);
            ShowAssetInfo(ai, currPage);
        }

        public void ShowAssetInfoByWoCommandId(string strId, Page currPage)
        {
            var manager = new CoreManager();
            AssetInfo ai = manager.GetAssetInfoByWoCommandId(strId);
            ShowAssetInfo(ai, currPage);
        }

        public void ShowAssetInfoByAssetId(string strId, Page currPage)
        {
            var manager = new CoreManager();
            AssetInfo ai = manager.GetAssetInfoByAssetId(strId);
            ShowAssetInfo(ai, currPage);
        }

        public void ShowAssetInfo(AssetInfo ai, Page currPage)
        {
            string strMenuId = currPage.Request.QueryString["MenuId"];
            if (ai == null)
                return;
            PageLoadHelper loadHelper = CurrPageLoadHelper;
            string strUrl = "../BaseData/ObjEdit.aspx?Hidden=Yes&MenuId=" + strMenuId + "&ClassName=" + ai.GetType().Name +
                            "&TypeName=" + ai.TypeName + "&" +
                            GetPageKeyField(ai.GetType().Name) + "=" +
                            ai.Id;
            string strClassMemo = loadHelper.XmlReader.GetNodeAttributeValue(ai.GetType().Name, loadHelper.MEMO);
            var win = new Window(currPage, strClassMemo + "明细");
            win.Width = 1000;
            win.Height = 660;
            win.ShowModalDialog(strUrl);
        }

        public void SetExecErrMsg(StringCollection scErr)
        {
            DataTable dt = null;

            if (scErr != null)
            {
                dt = new DataTable();
                dt.Columns.Add("错误描述", typeof (string));
                foreach (string str in scErr)
                {
                    dt.Rows.Add(new object[] {str});
                }
            }

            SetSessionObject(EXEC_ERR_MSG, dt);
        }

        public object GetExecErrMsg()
        {
            return GetSessionObject(EXEC_ERR_MSG);
        }

        public XmlNode GetSelectListSqlNode(string className, string typeName)
        {
            return
                CurrPageBuilder.m_LoadHelper.XmlReader.GetXmlNode("Setting/" + className + "/" + typeName +
                                                                  "/commandSetting/SelectListSql");
        }

        public string GetSelectListSqlValue(string className, string typeName)
        {
            XmlNode nd = GetSelectListSqlNode(className, typeName);
            string strSql = CurrObjXmlReader.GetNodeAttributeValue(nd, CurrPageLoadHelper.SQL, true);

            strSql = strSql.Replace("\r\n", " ");
            m_RuleHelper.SetConditionToSelectAssetSql(GetCurrSessionWoInfo(m_Page), ref strSql);
            return strSql;
        }

       
    }
}